import { BadRequestException, Inject, Injectable } from '@nestjs/common';
import { PrismaService } from 'src/prisma/prisma.service';

@Injectable()
export class ChatroomService {
  @Inject(PrismaService)
  private prismaService: PrismaService;

  @Inject()

  // 创建单聊
  async createOneToOneChatroom(userId: number, friendId: number) {
    // 往聊天室表插入一条数据
    const { id: roomId } = await this.prismaService.room.create({
      data: {
        name: '单聊' + Math.random().toString().slice(2, 8), // 前端可以处理为具体用户名，这个名称只做垫底用
        chatType: 'Private',
      },
      select: {
        id: true,
      },
    });

    // 把两个人拉入同一个聊天室
    await this.prismaService.userRoom.createMany({
      data: [
        {
          userId,
          roomId,
        },
        {
          userId: friendId,
          roomId,
        },
      ],
    });

    return roomId;
  }

  // 创建群聊
  async createGroupChatroom(
    userId: number,
    roomName: string,
    avatar: string,
    memberIds: number[],
  ) {
    const { id: roomId } = await this.prismaService.room.create({
      data: {
        name: roomName,
        avatar,
        chatType: 'Group',
      },
      select: {
        id: true,
      },
    });

    // 把自己拉入群聊中
    await this.prismaService.userRoom.createMany({
      data: [
        {
          userId,
          roomId,
        },
        ...memberIds.map((id) => ({
          userId: id,
          roomId,
        })),
      ],
    });
    return roomId;
  }

  // 用户的聊天室列表
  async list(userId: number, name: string) {
    // 1. 获取用户所在的所有聊天室ID
    const roomIds = await this.prismaService.userRoom.findMany({
      where: {
        userId,
      },
      select: {
        roomId: true,
      },
    });

    // 2. 根据聊天室ID获取聊天室信息
    const rooms = await this.prismaService.room.findMany({
      where: {
        id: {
          in: roomIds.map((item) => item.roomId),
        },
        name: {
          contains: name,
        },
      },
      select: {
        id: true,
        name: true,
        avatar: true,
        chatType: true,
        createTime: true,
      },
    });

    const result = [];

    // 3. 记录聊天室的用户人数以及信息
    for (let i = 0; i < rooms.length; i++) {
      const userIds = await this.prismaService.userRoom.findMany({
        where: {
          roomId: rooms[i].id,
        },
        select: {
          userId: true,
        },
      });

      if (rooms[i].chatType === 'Private') {
        // 获取另一个成员信息（用作群聊的名称和头像）
        const user = await this.prismaService.user.findUnique({
          where: {
            id: userIds.find((item) => item.userId !== userId).userId,
          },
        });
        if (user) {
          rooms[i].name = user.nickName;
          rooms[i].avatar = user.avatar;
        }
      }

      result.push({
        ...rooms[i],
        userCount: userIds.length,
        userIds: userIds.map((item) => item.userId),
      });
    }

    return result.sort((a, b) => b.createTime - a.createTime);
  }

  // 获取聊天室成员
  async members(roomId: number) {
    // 1. 获取聊天室成员ID
    const memberIds = await this.prismaService.userRoom.findMany({
      where: {
        roomId,
      },
      select: {
        userId: true,
      },
    });

    // 2. 根据成员ID获取成员信息
    const members = await this.prismaService.user.findMany({
      where: {
        id: {
          in: memberIds.map((item) => item.userId),
        },
      },
      select: {
        id: true,
        username: true,
        nickName: true,
        avatar: true,
        email: true,
        createTime: true,
      },
    });

    return members;
  }

  // 获取聊天室信息
  async info(roomId: number) {
    const room = await this.prismaService.room.findUnique({
      where: {
        id: roomId,
      },
    });

    return {
      ...room,
      users: await this.members(roomId),
    };
  }

  // 获取用户所在聊天室
  async find(userId: number, userIds: number[]) {
    const members = [userId, ...userIds];

    // 1. 查找包含这些用户的所有房间ID和用户ID: [{roomId, userId}, {roomId, userId}...]
    const userRooms = await this.prismaService.userRoom.findMany({
      where: {
        userId: { in: members },
      },
      select: {
        roomId: true,
        userId: true,
      },
    });

    // 2. 按 roomId 分组，收集每个房间的所有用户ID: {roomId: Set<userId>, roomId: Set<userId>...}
    const roomMap = new Map<number, Set<number>>();
    userRooms.forEach(({ roomId, userId }) => {
      if (!roomMap.has(roomId)) {
        roomMap.set(roomId, new Set());
      }
      roomMap.get(roomId).add(userId);
    });

    // 3. 查找符合条件的房间：用户ID集合完全匹配
    const result = [];
    for (const [roomId, userSet] of roomMap) {
      // 查询该房间的所有成员，确保包含所有成员: [{userId}, {userId}...]
      const allUsersInRoom = await this.prismaService.userRoom.findMany({
        where: { roomId },
        select: { userId: true },
      });

      const roomMembers = new Set(allUsersInRoom.map((user) => user.userId));

      // 检查房间成员是否完全匹配目标成员
      if (
        roomMembers.size === members.length && // 成员数量匹配
        members.every((id) => roomMembers.has(id))
      ) {
        result.push(roomId);
      }
    }
    return result;
  }

  // 把用户拉入房间
  async join(roomId: number, userIds: number[]) {
    // 单聊不允许拉人
    const room = await this.prismaService.room.findUnique({
      where: {
        id: roomId,
      },
      select: {
        chatType: true,
      },
    });
    if (room.chatType === 'Private') {
      throw new BadRequestException('单聊不允许拉人');
    }

    await this.prismaService.userRoom.createMany({
      data: userIds.map((userId) => ({
        roomId,
        userId,
      })),
    });
    return '加入成功';
  }

  // 把用户踢出房间
  async quit(roomId: number, userIds: number[]) {
    await this.prismaService.userRoom.deleteMany({
      where: {
        roomId,
        userId: {
          in: userIds,
        },
      },
    });
    return '退出成功';
  }

  // 销毁房间
  async destroy(roomId: number) {
    // 1. 删除房间消息
    await this.prismaService.message.deleteMany({
      where: {
        roomId,
      },
    });
    // 2. 删除房间成员
    await this.prismaService.userRoom.deleteMany({
      where: {
        roomId,
      },
    });
    // 3. 删除房间
    await this.prismaService.room.delete({
      where: {
        id: roomId,
      },
    });

    return '销毁成功';
  }

  // 添加未读消息数
  async addUnread(userId: number, roomId: number, messageId: number) {
    return await this.prismaService.userRoom.update({
      where: {
        userId_roomId: {
          userId,
          roomId,
        },
      },
      data: {
        unreadCount: {
          increment: 1,
        },
        lastUnreadMessageId: messageId,
      },
    });
  }

  // 获取未读消息数以及最后一条未读消息
  async getUnread(userId: number) {
    return await this.prismaService.userRoom.findMany({
      where: {
        userId,
      },
      select: {
        roomId: true,
        unreadCount: true,
        lastUnreadMessage: {
          select: {
            id: true,
            content: true,
            type: true,
            createTime: true,
          },
        },
      },
    });
  }

  // 清空未读消息
  async clearUnread(userId: number, roomId: number) {
    return await this.prismaService.userRoom.update({
      where: {
        userId_roomId: {
          userId,
          roomId,
        },
      },
      data: {
        unreadCount: 0,
        lastUnreadMessageId: null,
      },
    });
  }
}
